在第一篇我們說到會介紹一點 functional programming (FP) ,不過不用太緊張,我們不會很深入 FP 的概念,我想應該有不少人,看了一些 FP 的教學,結果馬上就看到 Monad 這個不知道那是什麼的東西,就讀不下去了
但不用擔心,你不需要知道什麼是 Monad 也可以使用 Effect ,而且我也不會介紹到那些專有名詞
數學上的函數是指給一輸入,經函數的計算後,會被對應到另一個值
像上面的函數就是當 x 輸入 1 ,則你會拿到 2 ,輸入 2 會拿到 4 ,輸出的值會等於輸入的值乘以 2 ,以程式碼表示就變成
function f(x: number) {
return x * 2
}
我們再來看一下比較複雜的範例,如果我們要對一個數字陣列,每個值都乘以 2 ,其中一個寫法會是像這樣
function allTimesTwo(input: number[]) {
const result = []
for (const item of input) {
result.push(item * 2)
}
return result
}
那如果要對每個元素加 1 呢?
function allPlusOne(input: number[]) {
const result = []
for (const item of input) {
result.push(item + 1)
}
return result
}
有沒有注意到,除了中間的 item * 2
與 item + 1
不同外,其它的部份都一樣,那我們有沒有可能將中間的部份單獨抽出來,答案是有的,我們可以將中間的部份變成一個 function
傳入
function allDoSomething(input: number[], f: (item: number) => number) {
const result = []
for (const item of input) {
result.push(f(item))
}
return result
}
使用上就只需要像這樣
allDoSomething(list, (item) => item * 2) // 這個相當於 allTimesTwo
allDoSomething(list, (item) => item + 1) // 這個相當於 allPlusOne
不知道這樣有沒有讓你想到,在原生的 JavaScript 中,我們可能會像這樣處理
list.map((item) => item * 2)
list.map((item) => item + 1)
那如果要先乘以 2 再都加 1 呢?
list
.map((item) => item * 2)
.map((item) => item + 1)
這上面展示了兩個 FP (Functional Programming) 的概念
Effect 是一個比較偏向 FP 的套件,官方也做了很多方便 FP 開發的設計,比如
以上面 allDoSomething
而言
data-first:
allDoSomething(list, (item) => item * 2)
data-last:
allDoSomething((item) => item * 2, list)
像這樣看資料是放在第一個參數還是最後一個參數,而 Effect 的 function 還有進一步的設計,讓你可以像這樣呼叫
allDoSomething((item) => item * 2)(list)
另外搭配一個內建的 pipe 的 function ,pipe 會把第一個參數傳給下一個 function ,並把第一個 function 的結果再傳給第二個 function ,依此類推,會變的像這樣
pipe(
list,
allDoSomething((item) => item * 2),
allDoSomething((item) => item + 1),
)
這代表的是都先乘 2 再加 1 ,之後我們很可能會看到這樣的寫法
下一篇要來介紹的是為什麼我們需要 Effect